package cn.kgc.controller;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.StrUtil;
import cn.kgc.entity.Depts;
import cn.kgc.entity.Roles;
import cn.kgc.entity.Users;
import cn.kgc.form.UsersAddForm;
import cn.kgc.form.UsersUpdateForm;
import cn.kgc.service.DeptsService;
import cn.kgc.service.RolesService;
import cn.kgc.service.UsersService;
import cn.kgc.service.impl.MenusServiceImpl;
import cn.kgc.util.Pager;
import cn.kgc.util.ResultConstant;
import cn.kgc.util.SystemConstant;
import cn.kgc.util.exception.HttpException;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author wangyue
 * @version 1.0
 */
@RestController
@RequestMapping("/users")
@Api(tags = "用户管理接口")
@Validated
@Slf4j
@CrossOrigin
@SuppressWarnings("all")
public class UsersController {
    @Resource
    private UsersService usersService;
    @Resource
    private DeptsService deptsService;
    @Resource
    private RolesService rolesService;
    @Autowired
    private MenusServiceImpl menusService;

    @GetMapping("/info")
    public Map<String, Object> info() {
        //1获得用户的路由信息
        //获得登录用户角色对应的菜单信息(不要使用我们之前定义的根据角色id获得菜单的方法！！！)
        //将菜单转为树形结构
        //将菜单信息转为路由信息

        return Map.of("allRouters",
                menusService.getRouterVoList(),
                "buttonPerms",
                //2获得用户的按钮信息
                menusService.getMenuPerms());
    }

    @PostMapping("/delete")
    @ApiOperation(value = "删除用户信息(包含批量删除)")
    @Transactional
    @CacheEvict(value = "users", key = "'detail'+#map.get('userIds')")
    public boolean delete(@RequestBody HashMap<String, Integer[]> map) {
        //获得要删除的用户id
        List<Integer> userIds = List.of(map.get("userIds"));
        //1 用户不能自己删除自己
        Integer loginUserId = 8;
        if (userIds.contains(loginUserId)) {
            throw new HttpException(ResultConstant.DELETE_USER_ERROR1);
        }
        //2 如果用户是部门负责人则不能删除
        for (Integer userId : userIds) {
            LambdaQueryWrapper<Depts> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(Depts::getUserId, userId);
            if (deptsService.count(queryWrapper) > 0) {
                throw new HttpException(ResultConstant.DELETE_USER_ERROR2);
            }
        }
        //3 如果用户是系统管理员则不能删除
        for (Integer userId : userIds) {
            Users users = usersService.getById(userId);
            if (users != null) {
                if (users.getRoleId() == SystemConstant.USER_ADMIN_ROLE_ID) {
                    throw new HttpException(ResultConstant.DELETE_USER_ERROR3);
                }
            }
        }
        //批量删除用户
        return usersService.removeByIds(userIds);
    }

    @PostMapping("/save")
    @ApiOperation(value = "添加用户信息")
    public boolean save(@RequestBody @Validated UsersAddForm form) {
        //todo 用户名是否重复
        Users users = new Users();
        BeanUtil.copyProperties(form, users);
        //todo 密码进行加密
        users.setUserPwd(form.getMobile());
        return usersService.save(users);
    }


    @GetMapping("/detail/{id}")
    @ApiOperation(value = "查看用户详细信息")
    @Cacheable(value = "users", key = "#root.methodName+#id")
    public Users detail(@PathVariable("id") Integer id) {
        return usersService.getById(id);
    }

    @GetMapping("/list")
    @ApiOperation(value = "分页查询数据")
    public Pager<Users> selectPage(@RequestBody HashMap<String, Object> params) {
        int pageNum = MapUtil.getInt(params, "pageNum");
        int pageSize = MapUtil.getInt(params, "pageSize");
        String userName = MapUtil.getStr(params, "userName");
        String mobile = MapUtil.getStr(params, "mobile");
        int state = MapUtil.getInt(params, "state");
        int deptId = MapUtil.getInt(params, "deptId");
        int roleId = MapUtil.getInt(params, "roleId");
        LambdaQueryWrapper<Users> queryWrapper = new LambdaQueryWrapper<>();
        //封装查询条件
        queryWrapper.likeRight(StrUtil.isNotBlank(userName), Users::getUserName, userName);
        queryWrapper.eq(StrUtil.isNotBlank(mobile), Users::getMobile, mobile);
        queryWrapper.eq(state != 0, Users::getState, state);
        queryWrapper.eq(deptId != 0, Users::getDeptId, deptId);
        queryWrapper.eq(roleId != 0, Users::getRoleId, roleId);
        //分页条件
        Page<Users> page = new Page<>(pageNum, pageSize);
        Pager<Users> pager = Pager.build(usersService.page(page, queryWrapper));
        //获得当前页的用户信息
        List<Users> currentPageRecords = pager.getCurrentPageRecords();
        //遍历用户的信息
        currentPageRecords.forEach(user -> {
            int tempId = user.getRoleId();
            Roles roles = rolesService.getById(tempId);
            if (roles != null) {
                user.setRoleName(roles.getRoleName());
            }
        });
        //分页查询用户信息
        return pager;
    }


    @PostMapping("/update")
    @ApiOperation(value = "修改用户信息")
    @CacheEvict(value = "users", key = "'detail'+#form.getUserId()")
    public boolean update(@RequestBody UsersUpdateForm form) {
        //验证用户名是否重名
        checkUserName(form.getUserName(), form.getUserId());
        //修改用户信息
        Users users = usersService.getById(form.getUserId());
        if (users != null) {
            BeanUtil.copyProperties(form, users);
            return usersService.updateById(users);
        }
        return false;
    }

    private void checkUserName(String userName, int userId) {
        LambdaQueryWrapper<Users> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Users::getUserName, userName);
        queryWrapper.ne(Users::getUserId, userId);
        if (usersService.count(queryWrapper) > 0) {
            throw new HttpException(ResultConstant.UPDATE_USER_NAME_REPEAT_ERROR);
        }
    }
}
